package com.example.java_message_queue.mqserver.core;

import com.example.java_message_queue.common.BasicProperties;

import java.io.*;
import java.util.Arrays;
import java.util.UUID;

public class Message implements Serializable {
    // private static final long serialVersionUID = 0x1L;

    // BasicProperties + body 是一个 Message 在网络上传输的信息.
    private BasicProperties basicProperties = new BasicProperties();
    private byte[] body;

    // 消息在文件中对应的 offset 的范围, [offsetBeg, offsetEnd)
    // 从这个范围取出的 byte[] 正好可以反序列化成一个 Message 对象.
    // offsetBeg 前面的 4 个字节是消息的长度
    private transient long offsetBeg = 0;
    private transient long offsetEnd = 0;

    // 消息在文件中是否有效. 0x0 表示无效, 0x1 表示有效
    private byte isValid = 0x1;

    // 创建新的消息, 同时给该消息分配一个新的 messageId
    // routingKey 以参数的为准. 会覆盖掉 basicProperties 中的 routingKey
    public static Message createMessageWithId(String routingKey, BasicProperties basicProperties, byte[] body) {
        Message message = new Message();
        if (basicProperties != null) {
            message.basicProperties = basicProperties;
        }
        message.basicProperties.setMessageId("M-" + UUID.randomUUID().toString());
        message.basicProperties.setRoutingKey(routingKey);
        message.body = body;
        return message;
    }

    public String getMessageId() {
        return basicProperties.getMessageId();
    }

    public String getRoutingKey() {
        return basicProperties.getRoutingKey();
    }

    public BasicProperties getBasicProperties() {
        return basicProperties;
    }

    public byte[] getBody() {
        return body;
    }

    public void setMessageId(String messageId) {
        basicProperties.setMessageId(messageId);
    }

    public void setRoutingKey(String routingKey) {
        basicProperties.setRoutingKey(routingKey);
    }

    public int getDeliveryMode() {
        return basicProperties.getDeliveryMode();
    }

    public void setDeliveryMode(int mode) {
        basicProperties.setDeliveryMode(mode);
    }

    public void setBasicProperties(BasicProperties basicProperties) {
        this.basicProperties = basicProperties;
    }

    public void setBody(byte[] body) {
        this.body = body;
    }

    public long getOffsetBeg() {
        return offsetBeg;
    }

    public void setOffsetBeg(long offsetBeg) {
        this.offsetBeg = offsetBeg;
    }

    public long getOffsetEnd() {
        return offsetEnd;
    }

    public void setOffsetEnd(long offsetEnd) {
        this.offsetEnd = offsetEnd;
    }

    public byte getIsValid() {
        return isValid;
    }

    public void setIsValid(byte isValid) {
        this.isValid = isValid;
    }

    // 把 Message 对象转成二进制字节数组
    // 关于序列化的思考:
    // 1. 使用 jackson 是不合适的. 因为 body 部分是 byte[]
    // 2. 使用 Java 自带的序列化, 需要对一个文件中混合的多个对象, 进行区分.
//    public static byte[] toBytes(Message message) throws IOException {
//        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//        try (ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream)) {
//            outputStream.writeObject(message);
//        }
//        return byteArrayOutputStream.toByteArray();
//    }

    // 从二进制解析成对象
//    public static Message fromBytes(byte[] data) {
//        Message message = null;
//        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
//        try (ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream)) {
//            message = (Message) objectInputStream.readObject();
//        } catch (IOException | ClassNotFoundException e) {
//            e.printStackTrace();
//        }
//        return message;
//    }


    @Override
    public String toString() {
        return "Message{" +
                "basicProperties=" + basicProperties +
                ", body=" + Arrays.toString(body) +
                ", offsetBeg=" + offsetBeg +
                ", offsetEnd=" + offsetEnd +
                ", isValid=" + isValid +
                '}';
    }
}
